package cn.edu.jgsu.jgsuchat.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisZSetCommands;
import org.springframework.data.redis.core.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * 作者: xyn
 * 创建时间: 2020/3/25 上午3:08
 */
@RequestMapping("myRedisController")
@RestController
public class MyRedisController {
    @Autowired
    private RedisTemplate redisTemplate = null;

    @Autowired
    private StringRedisTemplate stringRedisTemplate = null;
    @RequestMapping("/set")
    public void 操作set() {
        // 请注意：这里v1重复2次，由于集合不允许重复，所以只是插入5个成员到集合中
        stringRedisTemplate.opsForSet().add("set1", "v1", "v1", "v2", "v3", "v4", "v5");//set16个能插入5个
        stringRedisTemplate.opsForSet().add("set2", "v2", "v4", "v6", "v8");//set2都能插入
        // 绑定set1集合操作
        BoundSetOperations setOps = stringRedisTemplate.boundSetOps("set1");
        // 增加两个元素
        setOps.add("v6", "v7");
        // 删除两个元素
        setOps.remove("v1", "v7");
        // 返回所有元素
        Set set1 = setOps.members();//返回无序的set
        // 求成员数
        Long size = setOps.size();
        // 求交集
        Set inter = setOps.intersect("set2");
        // 求交集，并且用新集合inter保存
        setOps.intersectAndStore("set2", "inter");
        // 求差集,仅仅把结果放在变量diff中,仅此而已
        Set diff = setOps.diff("set2");
        // 求差集，并且用新集合my_diff保存(不仅会求出差集还会用destkey作为set名存到redis中
        setOps.diffAndStore("set2", "my_diff");
        // 求并集
        Set union = setOps.union("set2");
        // 求并集，并且用新集合union保存
        setOps.unionAndStore("set2", "union");
    }
    @RequestMapping("/zset")
    public void 操作zset() {
        Set<ZSetOperations.TypedTuple<String>> typedTupleSet = new HashSet<>();
        for (int i = 1; i <= 9; i++) {
            // 分数
            double score = i * 0.1;
            // 创建一个TypedTuple对象，存入值和分数
            ZSetOperations.TypedTuple<String> typedTuple = new DefaultTypedTuple<String>("value" + i, score);
            typedTupleSet.add(typedTuple);
        }
        // 往有序集合插入元素
        stringRedisTemplate.opsForZSet().add("zset1", typedTupleSet);
        // 绑定zset1有序集合操作
        BoundZSetOperations<String, String> zsetOps = stringRedisTemplate.boundZSetOps("zset1");
        // 增加一个元素
        zsetOps.add("value10", 0.26);
        //获取索引1-6的元素
        Set<String> setRange = zsetOps.range(1, 6);
        // 按分数排序获取有序集合
        Set<String> setScore = zsetOps.rangeByScore(0.2, 0.6);
        // 定义值范围
        RedisZSetCommands.Range range = new RedisZSetCommands.Range();
        range.gt("value3");// 大于value3
        // range.gte("value3");// 大于等于value3
        // range.lt("value8");// 小于value8
        range.lte("value8");// 小于等于value8
        // 按值排序，请注意这个排序是按字符串排序
        Set<String> setLex = zsetOps.rangeByLex(range);
        // 删除元素
        zsetOps.remove("value9", "value2");
        // 求分数
        Double score = zsetOps.score("value8");
        // 在下标区间下，按分数排序，同时返回value和score
        Set<ZSetOperations.TypedTuple<String>> rangeSet = zsetOps.rangeWithScores(1, 6);
        // 在分数区间下，按分数排序，同时返回value和score
        Set<ZSetOperations.TypedTuple<String>> scoreSet = zsetOps.rangeByScoreWithScores(1, 6);
        // 按从大到小排序
        Set<String> reverseSet = zsetOps.reverseRange(2, 8);

    }
    @RequestMapping("/hash")
    public void 操作hash() {
        Map<String, String> hash = new HashMap<String, String>();
        hash.put("吴泽奇", "天气冷,吃点好的");
        hash.put("唐凯", "黄焖鸡");
        hash.put("江庆旺", "美食美客");
        // 存入一个散列数据类型
        stringRedisTemplate.opsForHash().putAll("hash", hash);
        stringRedisTemplate.opsForHash().put("hash", "吴泽奇","黄焖鸡");
    }
    @RequestMapping("/list")
    public void 操作list() {
        // 插入两个列表,注意它们在链表的顺序
        // 链表从左到右顺序为v10,v8,v6,v4,v2
        //left就是上,right就是下
        stringRedisTemplate.opsForList().leftPushAll("list1", "v2", "v4", "v6", "v8", "v10");
        // 链表从左到右顺序为v1,v2,v3,v4,v5,v6
        stringRedisTemplate.opsForList().rightPushAll("list2", "v1", "v2", "v3", "v4", "v5", "v6");
        // 绑定list2链表操作
        BoundListOperations listOps = stringRedisTemplate.boundListOps("list2");
        // 从右边弹出一个成员(从下边弹出来一个成员)
        Object result1 = listOps.rightPop();
        // 根据索引获取元素，Redis从0开始计算,这里值为v2
        Object result2 = listOps.index(1);
        // 从左边插入链表
        listOps.leftPush("v0");
        // 求链表长度
        Long size = listOps.size();
        // 求链表下标区间成员，整个链表下标范围为0到size-1，这里不取最后一个元素
        List elements = listOps.range(0, size - 2);
    }

}
